using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.IO;
using UnityEngine.Networking;


public class AudioVolumeManager : MonoBehaviour
{
    Transform audio_parent_trans;

    public float base_volume
    {
        get
        {
            return BdTools.Values.base_volume;
        }
        set
        {
            set_volume_by_config_file(is_bgm: false, value: value);
        }
    }
    public float bgm_volume
    {
        get
        {
            return BdTools.Values.bgm_volume;
        }
        set
        {
            set_volume_by_config_file(is_bgm: true, value: value);
        }
    }
    
    // Start is called before the first frame update
    void Start()
    {
        audio_parent_trans = BdTools.get_game_object_by_path("/ObjectPoolParent/AudioParent").transform;
    }

    [Header("bgm播放组件")]
    public AudioSource bgm_audio_source_comp;

    [Header("音效播放组件")]
    public AudioSource base_audio_source_comp;

    // Update is called once per frame
    void Update()
    {
        // ---- 音量监控
        if (!Mathf.Approximately(bgm_audio_source_comp.volume, BdTools.Values.bgm_volume))
        {
            bgm_audio_source_comp.volume = BdTools.Values.bgm_volume;
        }
        if (!Mathf.Approximately(base_audio_source_comp.volume, BdTools.Values.base_volume))
        {
            base_audio_source_comp.volume = BdTools.Values.base_volume;
        }
    }
    
    public IEnumerator load_audio_clip_to_dc(Dictionary<string, AudioClip> _audio_clip_dc, string audio_path, string audio_name="")
    {
        AudioType _audioType;
        audio_name = BdUtils.is_null(audio_name) ? audio_name : Path.GetFileName(audio_path);
        
        BdUtils.check_file_extension(audio_path, new List<string>(){"mp3", "wav"});
        if (BdUtils.check_file_extension(audio_path, "mp3", raise_error: false))
        {
            _audioType = AudioType.MPEG;
        }
        else
        {
            _audioType = AudioType.WAV;
        }

        string rel_path = Path.GetRelativePath(Application.streamingAssetsPath, audio_path);
        BdUtils.assert(BdUtils.exists_file(audio_path), 
            $"音频文件不存在? audio_path: {rel_path}");

        if (audio_path.StartsWith(Application.persistentDataPath))
        {
            audio_path = "file://" + audio_path;
            BdPackage.BdUtils.log("--- audio_path.StartsWith(Application.persistentDataPath), new audio_path:", audio_path);
        }
        UnityWebRequest _unityWebRequest = UnityWebRequestMultimedia.GetAudioClip(audio_path, _audioType);
        yield return _unityWebRequest.SendWebRequest();
        
        if(_unityWebRequest.result == UnityWebRequest.Result.ProtocolError || _unityWebRequest.result == UnityWebRequest.Result.ConnectionError)
        {
            Debug.Log(_unityWebRequest.error.ToString());
        }
        else
        {
            AudioClip _audioClip = DownloadHandlerAudioClip.GetContent(_unityWebRequest);
            _audio_clip_dc[audio_name] = _audioClip;
        }
    }

    public Dictionary<string, AudioClip> audio_clip_dc = new Dictionary<string, AudioClip>();
    
    public void play_audio(string audio_name="", float volume = 0.5f, float pitch = 1f, float recycle_time = 3f)
    {
        var audio_obj = ObjectPool.instance.GetObj("PlayAudioClip", prefab_path: "Prefabs/obj");
        audio_obj.transform.SetParent(audio_parent_trans);

        // AudioClip clip = Resources.Load<AudioClip>(path);
        BdPackage.BdUtils.assert(audio_clip_dc.ContainsKey(audio_name), $"key不存在? audio_clip_dc.audio_name: [{audio_name}]");
        AudioClip clip = audio_clip_dc[audio_name];
        // BdUtils.assert(clip, $"audio_name[{audio_name}]对应的`clip`为空?");

        var audio_comp = audio_obj.GetComponent<AudioSource>();
        audio_comp.PlayOneShot(clip);
        audio_comp.pitch = pitch;
        audio_comp.volume = volume * base_volume;
        ObjectPool.instance.RecycleObj(audio_obj, recycle_time);
    }

    public static AudioVolumeManager instance;
    
    private void Awake()
    {
        if (instance != null)
            Destroy(this);
        instance = this;
        
        // StartCoroutine(load_audio_clip_to_dc(audio_clip_dc, audio_path_i, audio_name_i));
        //
        // var audio_name_ls = new List<string>()
        // {
        //     "wave_lash_1.mp3",
        //     "wave_lash_2.mp3",
        //     "hit_by_lash.mp3",
        //     "haha.mp3"
        // };
        // foreach (var audio_name_i in audio_name_ls)
        // {
        //     string audio_path_i =  Application.streamingAssetsPath + $"/data/audio/{audio_name_i}";
        //     StartCoroutine(load_audio_clip_to_dc(audio_clip_dc, audio_path_i, audio_name_i));
        // }
    }

    public string get_audio_key(bool is_bgm)
    {
        string key = is_bgm ? "bgm_volume" : "base_volume";
        return key;
    }

    public float get_audio_value(bool is_bgm)
    {
        string audio_key = get_audio_key(is_bgm);
        float value = volume_file_obj.content_dc.TryGetValue(audio_key, out object _value) ? BdUtils.conv_to_float(_value) : 0.5f;
        return value;
    }

    private AppFileTools.FileObject _volume_file_obj;
    public AppFileTools.FileObject volume_file_obj
    {
        get
        {
            if(_volume_file_obj == null)
                _volume_file_obj = new AppFileTools.FileObject(file_name: "volume.json", dir_name:"archives", create_if_not_exists: true);
            return _volume_file_obj;
        }
    }

    public void init_volume()
    {
        set_volume_by_config_file(is_bgm: true);
        set_volume_by_config_file(is_bgm: false);
    }
    
    public void set_volume_by_config_file(bool is_bgm = true, float value = BdUtils.DEFAULT_FLOAT)
    {
        if (Mathf.Approximately(value, BdUtils.DEFAULT_FLOAT))
        {
            float audio_value = get_audio_value(is_bgm);
            value = audio_value;
        }
        else
        {
            string _audio_key = is_bgm ? "bgm_volume" : "base_volume";
            volume_file_obj.content_dc[_audio_key] = value;
            volume_file_obj.save();
        }
        
        if (is_bgm)
            BdTools.Values.bgm_volume = value;
        else
            BdTools.Values.base_volume = value;
        
        if (Mathf.Approximately(value, BdUtils.DEFAULT_FLOAT))
            BdUtils.log($"*** 初始化背景音乐 bgm_volume: {BdTools.Values.bgm_volume}, base_volume: {BdTools.Values.base_volume}");
    }
    
    public void btn_change_bgm_playing_state()
    {
        // --- 改变bgm的播放状态
        // bgm_audio_source_comp
        if (bgm_audio_source_comp == null)
        {
            Debug.LogError("BGM audio source component is not assigned!");
            return;
        }

        if (bgm_audio_source_comp.isPlaying)
        {
            PauseBGM();
        }
        else
        {
            PlayBGM();
        }
    }

    public bool get_bgm_playing_state()
    {
        return bgm_audio_source_comp.isPlaying;
    }
    
    // 播放背景音乐
    private void PlayBGM()
    {
        if (!bgm_audio_source_comp.isPlaying)
        {
            bgm_audio_source_comp.Play();
        }
    }

    // 暂停背景音乐
    private void PauseBGM()
    {
        if (bgm_audio_source_comp.isPlaying)
        {
            bgm_audio_source_comp.Pause();
        }
    }
    
    // 重新开始播放背景音乐
    public void btn_replay_bgm()
    {
        if (bgm_audio_source_comp.isPlaying)
        {
            bgm_audio_source_comp.Stop();
        }
        bgm_audio_source_comp.Play();
    }
}
